package com.watson.todolist.database;

import java.io.IOException;
import java.security.GeneralSecurityException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

import android.util.Base64;

/**
 * This class handles encrypting text. This is a generic method for encryption.
 * 
 * @author Donnie Ward
 * 
 * @since 1.0
 */
public class GenericEncryption {

	/**
	 * Unique code to encrypt text
	 */
	private static final char[] ENCRYPT_PASSWORD = "echosshgthaaecho"
			.toCharArray();

	/**
	 * Random bits
	 */
	private static final byte[] SALT = { (byte) 0xde, (byte) 0x33, (byte) 0x10,
			(byte) 0x12, (byte) 0xde, (byte) 0x33, (byte) 0x10, (byte) 0x12, };

	/**
	 * Handles encrypting text
	 * 
	 * @param text
	 *            - The text to encrypt
	 * @return text - the encrypted text
	 * @throws GeneralSecurityException
	 */
	public static String encrypt(String text) throws GeneralSecurityException {
		SecretKeyFactory keyFactory = SecretKeyFactory
				.getInstance("PBEWithMD5AndDES");
		SecretKey key = keyFactory.generateSecret(new PBEKeySpec(
				ENCRYPT_PASSWORD));
		Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
		pbeCipher
				.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
		return base64Encode(pbeCipher.doFinal(text.getBytes()));
	}

	/**
	 * 
	 * @param bytes
	 *            - The final bytes from the encryption transformation
	 * @return
	 */
	private static String base64Encode(byte[] bytes) {
		return Base64.encodeToString(bytes, Base64.DEFAULT);
	}

	/**
	 * Handles decrypting text
	 * 
	 * @param text
	 *            - The text to encrypt
	 * @return text - the decrypted text
	 * @throws GeneralSecurityException
	 * @throws IOException
	 */
	public static String decrypt(String text) throws GeneralSecurityException,
			IOException {
		SecretKeyFactory keyFactory = SecretKeyFactory
				.getInstance("PBEWithMD5AndDES");
		SecretKey key = keyFactory.generateSecret(new PBEKeySpec(
				ENCRYPT_PASSWORD));
		Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
		pbeCipher
				.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(SALT, 20));
		return new String(pbeCipher.doFinal(base64Decode(text)));
	}

	/**
	 * Decode the Base64-encoded data in input and return the data in a new byte
	 * array.
	 * 
	 * @param property
	 *            - text to decode
	 * @return decode - decoded data
	 * @throws IOException
	 */
	private static byte[] base64Decode(String property) throws IOException {
		return Base64.decode(property, Base64.DEFAULT);
	}

}
